package azServiceLayer;

import java.net.URL;

import javax.sound.midi.MidiSystem;
import javax.sound.midi.Receiver;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

import aaGame.GameEngine;

/* Class for starting midi soundtracks and .au sound effect files */
public class AudioPlayer {
	// Midi soundtrack
	public Sequencer sequencer;
	private URL sequencerURL;
	private long midiPlayPosition;

	// .au sound effect
	public Clip clip;

	public int musicVolume;

//	GameEngine root;
	
	public static int MIDI = 0;
	public static int CLIP = 1;

	// Type 0 is a Midi soundtrack, while type 1 is an audiofile that is
	// compatible with the Clip class,
	// which are typically used for sound effects of the type .au
	public AudioPlayer(URL url, int type /*, GamePanel master */  ) {

//		root = master;
	
		if (type == 0) {
			try {
				midiPlayPosition = 0;
				sequencerURL = url;
				setUpSequencer();
				setLoop();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} else {
			try {
				AudioInputStream clipAudio = AudioSystem
						.getAudioInputStream(url);
				clip = AudioSystem.getClip();
				clip.open(clipAudio);

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void setLoop() {
		sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
	}

	public void decreaseMusicVolume() {
		if (musicVolume > 5) {
			musicVolume -= 5;
		}
		try {
			ShortMessage volumeMessage = new ShortMessage();
			for (int i = 0; i < 16; i++) {
				volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, 7,
						musicVolume);
				MidiSystem.getReceiver().send(volumeMessage, -1);
			}
		} catch (Exception e) {
			System.out.println("Exception: " + e.getMessage());
		}
	}

	public void increaseMusicVolume() {
		if (musicVolume < 122) {
			musicVolume += 5;
		}
		try {
			ShortMessage volumeMessage = new ShortMessage();
			for (int i = 0; i < 16; i++) {
				volumeMessage.setMessage(ShortMessage.CONTROL_CHANGE, i, 7,
						musicVolume);
				MidiSystem.getReceiver().send(volumeMessage, -1);
			}
		} catch (Exception e) {
			System.out.println("Exception: " + e.getMessage());
		}
	}

	/* Plays the .au sound effect */
	public void playClip() {
		clip.stop();
		clip.setFramePosition(0);
		clip.start();
	}

	public void playMusic() {
		musicVolume = 0;
		sequencer.setTickPosition(midiPlayPosition);
		sequencer.start();
//		for (int i = 0; i < root.volume; i += 5) {
//			increaseMusicVolume();
//			try {
//				Thread.sleep(5);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//		}
	}

	/* Stops the midi soundtrack */
	public void stopMusic() {
//		for (int i = root.volume; i > 0; i -= 5) {
//			decreaseMusicVolume();
//			try {
//				Thread.sleep(5);
//
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
		midiPlayPosition = sequencer.getTickPosition();
		sequencer.stop();
	}

	private void setUpSequencer() throws Exception {
		Sequence sequence = MidiSystem.getSequence(sequencerURL);
		sequencer = MidiSystem.getSequencer(false);
		Receiver receiver = MidiSystem.getReceiver();

		// open the sequencer and wire up the receiver and transmitter
		sequencer.open();
		sequencer.getTransmitter().setReceiver(receiver);
		sequencer.setSequence(sequence);
	}

}
